/**
 * Represents the vending company representative whose job it is to restock the
 * vending machine
 * 
 * @author SNelson
 * 
 */
public class VendingCompanyRepresentative extends Thread implements Schedulable
{
	/**
	 * The scheduler that notifies us of simulated time events
	 */
	private final Scheduler scheduler;
	/**
	 * The vending machine that this rep restocks
	 */
	private final VendingMachine machine;

	/**
	 * Whether or not to stop this thread
	 */
	private boolean stop = false;

	/**
	 * The name of the representative for printing
	 */
	public static final String NAME = "Vending Company Representative";

	/**
	 * Constructor
	 * 
	 * @param scheduler
	 *            The scheduler that will notify us of simulated time events
	 * @param machine
	 *            The vending machine that this representative restocks
	 */
	public VendingCompanyRepresentative(Scheduler scheduler,
		VendingMachine machine)
	{
		this.scheduler = scheduler;
		scheduler.addSchedulable(this);
		this.machine = machine;
		setName(NAME);
	}

	/**
	 * Called when a new day has begun
	 * 
	 * @param day
	 *            The numeric day in the simulation
	 */
	@Override
	public void onNewDay(int day)
	{
	}

	/**
	 * Called when a new hour begins
	 * 
	 * @param day
	 *            The numeric day in the simulation
	 * @param hour
	 *            The hour in the day
	 */
	@Override
	public void onHour(final int day, final int hour)
	{
		if (day % 3 == 0 && day != 0 && hour == 0)
		{
			synchronized (this)
			{
				notifyAll();
			}
		}
	}

	/**
	 * Called when the simulation ends
	 */
	public synchronized void onSimulationEnd()
	{
		scheduler.removeSchedulable(this);
		stop = true;
		notifyAll();
	}

	/**
	 * Body of this thread
	 */
	@Override
	public void run()
	{
		while (!stop)
		{
			synchronized (this)
			{
				try
				{
					wait();
				}
				catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (stop)
				{
					return;
				}

				VendingMachineTransaction.Builder builder = new VendingMachineTransaction.Builder(
					machine);
				VendingMachineTransaction transaction = builder
					.doSomething(new Runnable()
					{
						@Override
						public void run()
						{
							print("Attempting to restock vending machine");
						}
					}).restock().build();
				boolean success = machine.executeTransaction(transaction);
				if (success)
				{
					print("Restock successful");
				}
				else
				{
					print("Restock failed");
				}
			}
		}
	}

	/**
	 * Prints the given contents formatted for the vending rep
	 * 
	 * @param contents
	 *            The contents to print
	 */
	private void print(String contents)
	{
		System.out.println(scheduler.getFormattedTime() + " " + getName()
			+ ": " + contents);
	}
}
